﻿// Copyright (c) Microsoft Corporation.  All rights reserved. 
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;

namespace WiE.Utils
{
    /// <summary>
    /// Simple settings class that stores one or more pairs of string - value settings into the 
    /// user's hive under an application folder / hive specified by the m_strApplicationName.
    /// </summary>
    /// 
    class ApplicationSettings
    {
        private const string SOFTWARESUBKEYNAME = "Software\\Microsoft\\";

        private string m_strApplicationName = "SomeApplication";

        /// <summary>
        /// Default constructor
        /// </summary>
        public ApplicationSettings()
        {
        }

        /// <summary>
        /// Constructor allowing the specification of an application name.
        /// </summary>
        /// <param name="p_strApplicationName"></param>
        public ApplicationSettings(string p_strApplicationName)
        {
            m_strApplicationName = p_strApplicationName;
        }

        /// <summary>
        /// The name of the application to associate with the settings.
        /// </summary>
        public string ApplicationName
        {
            get { return m_strApplicationName; }
            set { m_strApplicationName = value; }
        }

        /// <summary>
        /// Retrieves an application setting for this application for this device 
        /// </summary>
        /// <param name="p_strSettingName"></param>
        /// <returns></returns>
        public string GetDeviceSetting(string p_strSettingName)
        {
            string strSettingValue = null;

            try
            {
                // Retrieve the value
                strSettingValue = GetSetting(Registry.LocalMachine, p_strSettingName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("There was an issue attempting to retrieve the setting {0}.  Exception: {1}", p_strSettingName, ex.ToString()));
            }

            return strSettingValue;
        }

        
        /// <summary>
        /// Saves a setting for the application that is "system-wide" (localmachine)
        /// </summary>
        /// <param name="p_strSettingName"></param>
        /// <param name="p_strSettingValue"></param>
        public void SaveDeviceSetting(string p_strSettingName, string p_strSettingValue)
        {
            try
            {
                SaveSetting(Registry.LocalMachine, p_strSettingName, p_strSettingValue);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("There was an issue saving the setting {0} with value '{1}'.  Exception: {2}.", p_strSettingName, p_strSettingValue, ex.ToString()));

                throw new Exception("Error while attempting to save the setting", ex);
            }
        }

        /// <summary>
        /// Retrieves the setting p_strSettingName as it is stored for the current user for the
        /// application.
        /// </summary>
        /// <param name="p_strSettingName"></param>
        /// <returns></returns>
        public string GetUserSetting(string p_strSettingName)
        {
            string strSettingValue = null;

            try
            {
                // Retrieve the value
                strSettingValue = GetSetting(Registry.CurrentUser, p_strSettingName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("There was an issue attempting to retrieve the setting {0}.  Exception: {1}", p_strSettingName, ex.ToString()));
            }

            return strSettingValue;
        }

        /// <summary>
        /// Saves a setting under the user's application hive
        /// </summary>
        /// <param name="p_strSettingName"></param>
        /// <param name="p_strSettingValue"></param>
        public void SaveUserSetting(string p_strSettingName, string p_strSettingValue)
        {
            try
            {
                SaveSetting(Registry.CurrentUser, p_strSettingName, p_strSettingValue);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("There was an issue saving the setting {0} with value '{1}'.  Exception: {2}.", p_strSettingName, p_strSettingValue, ex.ToString()));

                throw new Exception("Error while attempting to save the setting", ex);
            }
        }


        /// <summary>
        /// Helper method used by all the SaveXXX methods to write a new setting
        /// </summary>
        /// <param name="p_registryKeyStartHive"></param>
        /// <param name="p_strSettingName"></param>
        /// <param name="p_strSettingValue"></param>
        private void SaveSetting(RegistryKey p_registryKeyStartHive, string p_strSettingName, string p_strSettingValue)
        {
            string strSubKeyName = SOFTWARESUBKEYNAME + m_strApplicationName;

            // Open (or create) the application subfolder from the start hive in writeable mode
            RegistryKey appSettingsKey = p_registryKeyStartHive.CreateSubKey(strSubKeyName);

            // Attempt to save the value
            appSettingsKey.SetValue(p_strSettingName, p_strSettingValue, RegistryValueKind.String);

            // Close the registry
            appSettingsKey.Close();
        }

        /// <summary>
        /// Helper method for the GetXXX methods that retrieves a setting value for the 
        /// application under the hive specified by p_registryKeyStartHive.  This is useful
        /// for retrieving settings for CurrentUser or for LocalMachine.
        /// </summary>
        /// <param name="p_registryKeyStartHive"></param>
        /// <param name="p_strSettingName"></param>
        /// <returns></returns>
        private string GetSetting(RegistryKey p_registryKeyStartHive, string p_strSettingName)
        {
            string strSubKeyName = SOFTWARESUBKEYNAME + m_strApplicationName;

            string settingValue = null;

            // Open the application subfolder from the start hive in read only mode
            RegistryKey appSettingsKey = p_registryKeyStartHive.OpenSubKey(strSubKeyName, false);
            if (null != appSettingsKey)
            {
                // Attempt to retrieve the setting
                settingValue = (string) appSettingsKey.GetValue(p_strSettingName); 

                // Close the registry key
                appSettingsKey.Close();
            }

            // Return the results
            return (settingValue);
        }
    }
}
